#ifndef DBNONBLOCK_H
#define DBNONBLOCK_H

#include "Db.h"
#include "MsgQueue.h"

extern "C" {
    #include <pthread.h>
}

namespace ZY
{
    class DbNonblock : virtual public Db
    {
        public:
            struct CallBackResult {
                int type;
                bool success;
                int insertId;
                int affectRows;
                DbResult *dbResult;
                ByteString ext;

                ~CallBackResult();
            };

            DbNonblock();
            virtual ~DbNonblock();

            DbNonblock & QueryCallBack( SQL &sql , MsgQueue::CallbackFn _objCallBack );
            DbNonblock & QueryCallBack( SQL &sql , MsgQueue::CallbackFn _objCallBack  , ByteString & bs  );
            DbNonblock & QueryCallBack( const string & sql , MsgQueue::CallbackFn _objCallBack  );
            DbNonblock & QueryCallBack( const string & sql , MsgQueue::CallbackFn _objCallBack  , ByteString  &bs  );

            DbNonblock & QueryResultCallBack( SQL &sql , MsgQueue::CallbackFn _objCallBack );
            DbNonblock & QueryResultCallBack( SQL &sql , MsgQueue::CallbackFn _objCallBack  , ByteString & bs  );
            DbNonblock & QueryResultCallBack( const string &sql , MsgQueue::CallbackFn _objCallBack );
            DbNonblock & QueryResultCallBack( const string &sql , MsgQueue::CallbackFn _objCallBack  , ByteString & bs  );

            void addSwapExecQueue();

            static CallBackResult *GetCallBackResult( ByteString & bs );
            static void CallBackResultFree( CallBackResult *r );
            static void GetCallBackResult( CallBackResult & r , ByteString & bs );
            //需要调用
            static void runExecQueueDeamon( DbNonblock &db );
            static DbNonblock & getInstance();
            static DbNonblock & getInstance( int id );

        protected:
        private:

            struct execNode {
                int type;
                string sql;
                MsgQueue::CallbackFn callback;
                DbNonblock *db;
                ByteString ext;
            };

            DbNonblock & _QueryCallBack( int type , const string & sql , MsgQueue::CallbackFn _objCallBack , ByteString *bs );

            list<execNode*> _waitExecQueue;
            static list<execNode*> _waitSwapExecQueue;
            static list< execNode* > _execQueue;

            static pthread_mutex_t queueSwapLock;
            static pthread_cond_t execQueryReady;

            //需要由一个线程调用
            static void runExecQueue( DbNonblock *dbPointer ) ;
            static void _runExecQueue( );

            static map<int, DbNonblock *> _instance_map;
    };
}
#endif // DBNONBLOCK_H
